package xyz.zhzby.cyzx.acl.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import xyz.zhzby.cyzx.acl.entity.Permission;
import xyz.zhzby.cyzx.acl.entity.RolePermission;
import xyz.zhzby.cyzx.acl.entity.User;
import xyz.zhzby.cyzx.acl.helper.MemuHelper;
import xyz.zhzby.cyzx.acl.helper.PermissionHelper;
import xyz.zhzby.cyzx.acl.mapper.PermissionMapper;
import xyz.zhzby.cyzx.acl.service.IPermissionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import xyz.zhzby.cyzx.acl.service.IRolePermissionService;
import xyz.zhzby.cyzx.acl.service.IUserService;
import xyz.zhzby.cyzx.security.util.CyzxSecurityContextHolder;
import xyz.zhzby.cyzx.servicebase.domain.DataLogInfo;
import xyz.zhzby.cyzx.servicebase.domain.RestResponse;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 权限表 服务实现类
 * </p>
 *
 * @author zby
 * @since 2021-12-07
 */
@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements IPermissionService {
    @Autowired
    private IRolePermissionService rolePermissionService;

    @Autowired
    private IUserService userService;

    //获取全部菜单
    @Override
    public RestResponse<List<Permission>> queryAllMenu() {
        LambdaQueryWrapper<Permission> qw = new LambdaQueryWrapper<>();
        qw.orderByAsc(Permission::getId);
        List<Permission> permissionList = baseMapper.selectList(qw);
        List<Permission> result = bulid(permissionList);
        return RestResponse.success(result);
    }

    //根据角色获取菜单
    @Override
    public RestResponse<List<Permission>> selectAllMenu(Long roleId) {
        LambdaQueryWrapper<Permission> qw = new LambdaQueryWrapper<>();
        qw.orderByAsc(Permission::getId);
        List<Permission> allPermissionList = baseMapper.selectList(qw);

        //根据角色id获取角色权限
        LambdaQueryWrapper<RolePermission> qw1 = new LambdaQueryWrapper<>();
        qw1.eq(RolePermission::getRoleId, roleId);
        List<RolePermission> rolePermissionList = rolePermissionService.list(qw1);
        //转换给角色id与角色权限对应Map对象
        List<Long> permissionIdList = rolePermissionList.stream().map(RolePermission::getPermissionId).collect(Collectors.toList());
        allPermissionList.forEach(permission -> {
            permission.setSelect(permissionIdList.contains(permission.getId()));
        });
        List<Permission> permissionList = bulid(allPermissionList);
        return RestResponse.success(permissionList);
    }

    //给角色分配权限
    @Override
    public void saveRolePermissionRealtionShip(Long roleId, Long[] permissionIds) {
        LambdaQueryWrapper<RolePermission> qw = new LambdaQueryWrapper<>();
        qw.eq(RolePermission::getRoleId, roleId);
        rolePermissionService.remove(qw);

        xyz.zhzby.cyzx.security.entity.User subject = CyzxSecurityContextHolder.getSubject();
        List<RolePermission> rolePermissionList = new ArrayList<>();
        for (Long permissionId : permissionIds) {
            if (StringUtils.isEmpty(permissionId)) continue;

            RolePermission rolePermission = new RolePermission();
            rolePermission.setRoleId(roleId);
            rolePermission.setPermissionId(permissionId);
            rolePermissionList.add(rolePermission);
            subject.fillCreateInfo(rolePermission, DataLogInfo.USER_FIELD_ACTUAL_NAME);
        }
        rolePermissionService.saveBatch(rolePermissionList);
    }

    //根据用户id获取用户菜单
    @Override
    public List<String> selectPermissionValueByUserId(Long id) {

        List<String> selectPermissionValueList = null;
        if (this.isSysAdmin(id)) {
            //如果是系统管理员，获取所有权限
            selectPermissionValueList = baseMapper.selectAllPermissionValue();
        } else {
            selectPermissionValueList = baseMapper.selectPermissionValueByUserId(id);
        }
        return selectPermissionValueList;
    }

    @Override
    public List<JSONObject> selectPermissionByUserId(Long userId) {
        List<Permission> selectPermissionList = null;
        if (this.isSysAdmin(userId)) {
            //如果是超级管理员，获取所有菜单
            selectPermissionList = baseMapper.selectList(null);
        } else {
            selectPermissionList = baseMapper.selectPermissionByUserId(userId);
        }

        List<Permission> permissionList = PermissionHelper.bulid(selectPermissionList);
        List<JSONObject> result = MemuHelper.bulid(permissionList);
        return result;
    }

    @Override
    public RestResponse<String> saveOne(Permission permission) {
        CyzxSecurityContextHolder.getSubject().fillCreateInfo(permission, DataLogInfo.USER_FIELD_ACTUAL_NAME);
        baseMapper.insert(permission);
        return RestResponse.success("创建成功");
    }

    @Override
    public RestResponse<String> updateOne(Permission permission) {
        CyzxSecurityContextHolder.getSubject().fillUpdateInfo(permission, DataLogInfo.USER_FIELD_ACTUAL_NAME);
        baseMapper.updateById(permission);
        return RestResponse.success("修改成功");
    }

    @Override
    public RestResponse<String> removePermissionById(Long permissionId) {
        rolePermissionService.removeByPermissionId(permissionId);
        removeChildById(permissionId);
        return RestResponse.success("移除成功");
    }

    @ApiOperation("判断用户是否系统管理员")
    private boolean isSysAdmin(Long userId) {
        User user = userService.getById(userId);

        if (null != user && "admin".equals(user.getUsername())) {
            return true;
        }
        return false;
    }

    @ApiOperation("递归获取子节点")
    private void selectChildListById(Long id, List<Long> idList) {
        LambdaQueryWrapper<Permission> qw = new LambdaQueryWrapper<>();
        qw.eq(Permission::getParentId, id);
        qw.select(Permission::getId);
        List<Permission> childList = baseMapper.selectList(qw);
        childList.stream().forEach(item -> {
            idList.add(item.getId());
            this.selectChildListById(item.getId(), idList);
        });
    }

    @ApiOperation("使用递归方法建菜单")
    private static List<Permission> bulid(List<Permission> treeNodes) {
        List<Permission> trees = new ArrayList<>();
        for (Permission treeNode : treeNodes) {
            if (treeNode.getParentId().equals(0L)) {
                treeNode.setLevel(1);
                trees.add(findChildren(treeNode, treeNodes));
            }
        }
        return trees;
    }

    @ApiOperation("递归查找子节点")
    private static Permission findChildren(Permission treeNode, List<Permission> treeNodes) {
        treeNode.setChildren(new ArrayList<Permission>());

        for (Permission it : treeNodes) {
            if (treeNode.getId().equals(it.getParentId())) {
                int level = treeNode.getLevel() + 1;
                it.setLevel(level);
                if (treeNode.getChildren() == null) {
                    treeNode.setChildren(new ArrayList<>());
                }
                treeNode.getChildren().add(findChildren(it, treeNodes));
            }
        }
        return treeNode;
    }

    @ApiOperation("递归删除菜单")
    private void removeChildById(Long id) {
        List<Long> idList = new ArrayList<>();
        this.selectChildListById(id, idList);

        idList.add(id);
        baseMapper.deleteBatchIds(idList);
    }

}

